﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace TPOJ.Core.Utils
{
    [StructLayout(LayoutKind.Sequential)]
    public struct SECURITY_ATTRIBUTES
    {
        public int Length;
        public IntPtr lpSecurityDescriptor;
        public bool bInheritHandle;
    }

    public enum JOBOBJECTINFOCLASS
    {

        /// JobObjectBasicAccountingInformation -> 1
        JobObjectBasicAccountingInformation = 1,

        JobObjectBasicLimitInformation,

        JobObjectBasicProcessIdList,

        JobObjectBasicUIRestrictions,

        JobObjectSecurityLimitInformation,

        JobObjectEndOfJobTimeInformation,

        JobObjectAssociateCompletionPortInformation,

        JobObjectBasicAndIoAccountingInformation,

        JobObjectExtendedLimitInformation,

        JobObjectJobSetInformation,

        MaxJobObjectInfoClass,
    }

    [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
    public struct JOBOBJECT_EXTENDED_LIMIT_INFORMATION
    {

        /// JOBOBJECT_BASIC_LIMIT_INFORMATION->_JOBOBJECT_BASIC_LIMIT_INFORMATION
        public JOBOBJECT_BASIC_LIMIT_INFORMATION BasicLimitInformation;

        /// IO_COUNTERS->_IO_COUNTERS
        public IO_COUNTERS IoInfo;

        /// SIZE_T->ULONG_PTR->unsigned int
        public uint ProcessMemoryLimit;

        /// SIZE_T->ULONG_PTR->unsigned int
        public uint JobMemoryLimit;

        /// SIZE_T->ULONG_PTR->unsigned int
        public uint PeakProcessMemoryUsed;

        /// SIZE_T->ULONG_PTR->unsigned int
        public uint PeakJobMemoryUsed;
    }

    [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
    public struct JOBOBJECT_BASIC_LIMIT_INFORMATION
    {

        /// LARGE_INTEGER->_LARGE_INTEGER
        public LARGE_INTEGER PerProcessUserTimeLimit;

        /// LARGE_INTEGER->_LARGE_INTEGER
        public LARGE_INTEGER PerJobUserTimeLimit;

        /// DWORD->unsigned int
        public uint LimitFlags;

        /// SIZE_T->ULONG_PTR->unsigned int
        public uint MinimumWorkingSetSize;

        /// SIZE_T->ULONG_PTR->unsigned int
        public uint MaximumWorkingSetSize;

        /// DWORD->unsigned int
        public uint ActiveProcessLimit;

        /// ULONG_PTR->unsigned int
        public uint Affinity;

        /// DWORD->unsigned int
        public uint PriorityClass;

        /// DWORD->unsigned int
        public uint SchedulingClass;
    }

    [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
    public struct IO_COUNTERS
    {

        /// ULONGLONG->unsigned __int64
        public ulong ReadOperationCount;

        /// ULONGLONG->unsigned __int64
        public ulong WriteOperationCount;

        /// ULONGLONG->unsigned __int64
        public ulong OtherOperationCount;

        /// ULONGLONG->unsigned __int64
        public ulong ReadTransferCount;

        /// ULONGLONG->unsigned __int64
        public ulong WriteTransferCount;

        /// ULONGLONG->unsigned __int64
        public ulong OtherTransferCount;
    }

    [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Explicit)]
    public struct LARGE_INTEGER
    {

        /// Anonymous_9320654f_2227_43bf_a385_74cc8c562686
        [System.Runtime.InteropServices.FieldOffsetAttribute(0)]
        public Anonymous_9320654f_2227_43bf_a385_74cc8c562686 Struct1;

        /// Anonymous_947eb392_1446_4e25_bbd4_10e98165f3a9
        [System.Runtime.InteropServices.FieldOffsetAttribute(0)]
        public Anonymous_947eb392_1446_4e25_bbd4_10e98165f3a9 u;

        /// LONGLONG->__int64
        [System.Runtime.InteropServices.FieldOffsetAttribute(0)]
        public long QuadPart;
    }

    [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
    public struct Anonymous_9320654f_2227_43bf_a385_74cc8c562686
    {

        /// DWORD->unsigned int
        public uint LowPart;

        /// LONG->int
        public int HighPart;
    }

    [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
    public struct Anonymous_947eb392_1446_4e25_bbd4_10e98165f3a9
    {

        /// DWORD->unsigned int
        public uint LowPart;

        /// LONG->int
        public int HighPart;
    }


    public static class NativeMethods
    {
        [DllImport("kernel32.dll", EntryPoint = "CloseHandle", SetLastError = true, CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        public extern static bool CloseHandle(IntPtr handle);

        [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        public static extern IntPtr CreateJobObject(ref SECURITY_ATTRIBUTES JobAttributes,
            [MarshalAs(UnmanagedType.LPTStr)]string strName);

        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern bool AssignProcessToJobObject(IntPtr hJob, IntPtr hProcess);

        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern bool TerminateJobObject(IntPtr hJob, uint exitCode);

        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern int GetLastError();

        /// Return Type: BOOL->int
        ///hJob: HANDLE->void*
        ///JobObjectInformationClass: JOBOBJECTINFOCLASS->_JOBOBJECTINFOCLASS
        ///lpJobObjectInformation: LPVOID->void*
        ///cbJobObjectInformationLength: DWORD->unsigned int
        [System.Runtime.InteropServices.DllImportAttribute("kernel32.dll", EntryPoint = "SetInformationJobObject")]
        [return: System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.Bool)]
        public static extern bool SetInformationJobObject([System.Runtime.InteropServices.InAttribute()] System.IntPtr hJob, JOBOBJECTINFOCLASS JobObjectInformationClass, [System.Runtime.InteropServices.InAttribute()] JOBOBJECT_EXTENDED_LIMIT_INFORMATION lpJobObjectInformation, uint cbJobObjectInformationLength);
    }
}
